<?php
// 应用公共文件
use job\ThinkQueueJob;
use think\facade\Log;
use think\response\Json;

/**
 * 生成excel A-AZ
 * @param $columnTotal
 * @return array|string
 */
function foundExcelColumnName($columnTotal) {
    if ($columnTotal > 702) {
        return '参数错误';
    }

    $_minBaseCode = 65;//asc2码，65代表A
    $_maxBaseCode = 90;//asc2码，90代表Z
    $_result = array();

    $_allBaseCode = array();
    for($i = $_minBaseCode; $i <= $_maxBaseCode; $i ++) {
        $_allBaseCode[] = chr($i);
    }

    $_firstCode = $_minBaseCode;
    $_secondFlag = 0;
    $_secondCode = $_minBaseCode - 1;
    for ($i=0; $i < $columnTotal; $i++) {
        if ($_firstCode > $_maxBaseCode) {
            $_firstCode = $_minBaseCode;
            ++ $_secondFlag;
            ++ $_secondCode;
        }

        if ($_secondFlag > 0) {
            $result[] = chr($_secondCode) . chr($_firstCode);
        } else {
            $result[] = chr($_firstCode);
        }

        ++ $_firstCode;
    }

    return $result;
}

/**
 * 统一返回参数
 * @param int $code
 * @param mixed $data
 * @param string $msg
 * @return Json
 */
function jsonReturn(int $code, mixed $data, string $msg = ''): Json
{
    //限制code参数值
    $code = in_array($code, [-1, 0, 1]) ? $code : 0;
    //处理token
    $access_token = request()->access_token ?? '';
    //返回数据
    $data = [
        'code' => $code,
        'data' => $data,
        'msg' => $msg ?: ($code == 1 ? '操作成功' : '操作失败'),
    ];
    //返回数据写入队列
    $data['request_id'] = request()->request_id;
    if ($data['request_id']) {
        //推送至系统日志队列
        ThinkQueueJob::sendMsg('UpdateSystemLog', '', $data);
    }
    //返回数据
    $data['access_token'] = $access_token;
    return json($data);
}

/**
 * 求两个日期之间相差的天数
 * @param string $date1
 * @param string $date2
 * @return int
 */
function diff_date(string $date1, string $date2):int
{
    if ($date1 > $date2) {
        $startTime = strtotime($date1);
        $endTime = strtotime($date2);
    } else {
        $startTime = strtotime($date2);
        $endTime = strtotime($date1);
    }
    $diff = $startTime - $endTime;
    $day = $diff / 86400;
    return intval($day);
}

/**
 * 生成订单号
 * @return string
 */
function generateOrderNo(): string
{
    return date('YmdHis') . substr(microtime(), 2, 6) . sprintf('%03d', rand(0, 999));
}

/**
 * 数组数据签名
 * @param array $params
 * @param string $nonceStr
 * @return string
 */
function arrayDataSignature(array $params, string $nonceStr = ''): string
{
    //加密KEY
    $key = '65696e5e3624af4e287bee8559b494d5';
    // 对数组的值按key排序
    ksort($params);
    // 生成url的形式
    $params = http_build_query($params);
    $str_params = $params . '&key=' . $key;
    // 生成sign
    Log::write($str_params, '同步订单至V1分润系统');
    return strtoupper(md5($str_params));
}

/**
 * 安全签名
 * @param array $params
 * @param string $appSecret
 * @return string
 */
function secureSignature(array $params, string $appSecret): string
{
    ksort($params);
    $tmpArray = [];
    if (!empty($params)) {
        foreach ($params as $key => $value) {
            is_array($value) && $value = json_encode($value, JSON_UNESCAPED_UNICODE + JSON_UNESCAPED_SLASHES);
            $tmpArray[] = $key . '=' . $value;
        }
    }
    $string = implode('&', $tmpArray);
    $hash = hash_hmac('sha1', $string, $appSecret);
    return md5($hash);
}

function arrayDataSignatureMall(array $params, string $nonceStr = ''): string
{
    //加密KEY
    $key = 'bbca092f1057dae33e03f136d172784c';
    // 对数组的值按key排序
    ksort($params);
    // 生成url的形式
    $params = http_build_query($params);
    $str_params = $params . '&key=' . $key;
    // 生成sign
    Log::write($str_params, '同步订单至V1分润系统');
    return strtoupper(md5($str_params));
}

/**
 * uuid唯一序列码
 * @param string $prefix
 * @return string
 */
function uuid(string $prefix = ''): string
{
    $chars = md5(uniqid(mt_rand(), true));
    $uuid = substr($chars, 0, 8);
    $uuid .= substr($chars, 8, 4);
    $uuid .= substr($chars, 12, 4);
    $uuid .= substr($chars, 16, 4);
    $uuid .= substr($chars, 20, 12);
    return $prefix . $uuid;
}

/**
 * 通过概率计算函数get_rand获取抽中的奖项id
 * @param $proArr
 * @return int
 */
function get_rand($proArr): int
{
    $result = null;
    //概率数组的总概率精度
    $proSum = array_sum($proArr);
    //概率数组循环
    foreach ($proArr as $key => $proCur) {
        $randNum = mt_rand(1, $proSum);
        if ($randNum <= $proCur) {
            $result = $key;
            break;
        } else {
            $proSum -= $proCur;
        }
    }
    unset ($proArr);
    return intval($result);
}

/**
 * 生成毫秒时间戳
 * @return int
 */
function getMillisecond(): int
{
    $mill_time = microtime();
    $timeInfo = explode(' ', $mill_time);
    return (int)sprintf('%d%03d', $timeInfo[1], $timeInfo[0] * 1000);
}

/**
 * httpGet请求
 * @param string $url
 * @param array $param
 * @return array
 */
function httpGet(string $url, array $param = []): array
{
    //实例化
    $client = new GuzzleHttp\Client();
    //发起请求
    $response = $client->get($url, $param);
    $body = $response->getBody();//获取相应体
    $content = $body->getContents();//获取目标页面
    $status_code = $response->getStatusCode();//获取状态码
    $content_type = $response->getHeaderLine('content-type');//获取头部信息
    //返回数据
    return [
        'body' => $body,
        'content' => $content,
        'status_code' => $status_code,
        'content_type' => $content_type
    ];
}

/**
 * httpPost请求
 * @param string $url
 * @param array $param
 * @param array $headers
 * @return array
 */
function httpPost(string $url, array $param = [], array $headers = []): array
{
    try{
        //实例化
        $client = new GuzzleHttp\Client();
        //发起请求
        $response = $client->request('POST', $url, array_merge($param, ['headers' => $headers]));
        $body = $response->getBody();//获取相应体
        $content = $body->getContents();//获取目标页面
        $status_code = $response->getStatusCode();//获取状态码
        $content_type = $response->getHeaderLine('content-type');//获取头部信息
        //返回数据
        return [
            'body' => $body,
            'content' => $content,
            'status_code' => $status_code,
            'content_type' => $content_type
        ];
    }catch (\think\exception\ErrorException $e){
        return [
            'body' => '',
            'content' => '',
            'status_code' => 400,
            'content_type' => ''
        ];
    }

}

/**
 * 把对象的某个列作为列表hash的Key
 * @param array $arr
 * @param string $key
 * @param string $value
 * @return array
 */
function arrayMap(array $arr, string $key, string $value = ''): array
{
    $newArr = [];
    if (!empty($arr)) {
        foreach ($arr as $row) {
            if ($value) {
                $newArr[$row[$key]] = $row[$value];
            } else {
                $newArr[$row[$key]] = $row;
            }
        }
    }
    return $newArr;
}

/**
 * 本地文件转Base64
 * @param string $file
 * @return string
 */
function fileToBase64(string $file): string
{
    $base64_file = '';
    if (file_exists($file)) {
        $mime_type = mime_content_type($file);
        $base64_data = base64_encode(file_get_contents($file));
        $base64_file = 'data:' . $mime_type . ';base64,' . $base64_data;
    }
    return $base64_file;
}

/**
 * 下载网络上的图片返回base64
 * @param string $url
 * @return string
 */
function downloadPictureToBase64(string $url): string
{
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($curl, CURLOPT_ENCODING, 'gzip');
    $data = curl_exec($curl);
    $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    curl_close($curl);
    if ($code == 200) {//把URL格式的图片转成base64_encode格式的！
        return "data:image/jpeg;base64," . base64_encode($data);
    }
    return '';
}

/**
 * 秒转时间格式
 * @param int $seconds
 * @return string
 */
function secToTime(int $seconds = 0): string
{
    $seconds = intval($seconds);
    if ($seconds > 3600) {
        $hours = intval($seconds / 3600);
        $minutes = $seconds % 3600;
        $time = $hours . ":" . gmstrftime('%M:%S', $minutes);
    } else {
        $time = gmstrftime('%H:%M:%S', $seconds);
    }
    return $time;
}

/**
 * 处理无限级分类，返回带有层级关系的树形结构
 * @param array $data 数据数组
 * @param int $root 根节点的父级id
 * @param string $id id字段名
 * @param string $pid 父级id字段名
 * @param string $child 树形结构子级字段名
 * @return array $tree 树形结构数组
 */
function getMultilevelTree(array $data, int $root = 0, string $id = 'id', string $pid = 'pid', string $child = 'child'): array
{
    $tree = [];
    $temp = [];
    foreach ($data as $key => $val) {
        $temp[$val[$id]] = &$data[$key];
    }
    foreach ($data as $key => $val) {
        $parentId = $val[$pid];
        if ($root == $parentId) {
            $tree[] = &$data[$key];
        } else {
            if (isset($temp[$parentId])) {
                $parent = &$temp[$parentId];
                $parent[$child][] = &$data[$key];
            }
        }
    }
    return $tree;
}

/**
 * 隐藏部分字符串
 * @param string $str
 * @param string $replacement
 * @param int $start
 * @param int $length
 * @return string
 */
function func_substr_replace(string $str, string $replacement = '*', int $start = 1, int $length = 3): string
{
    $len = mb_strlen($str, 'utf-8');
    if ($len > intval($start + $length)) {
        $str1 = mb_substr($str, 0, $start, 'utf-8');
        $str2 = mb_substr($str, intval($start + $length), NULL, 'utf-8');
    } else {
        $str1 = mb_substr($str, 0, 1, 'utf-8');
        $str2 = mb_substr($str, $len - 1, 1, 'utf-8');
        $length = $len - 2;
    }
    $new_str = $str1;
    for ($i = 0; $i < $length; $i++) {
        $new_str .= $replacement;
    }
    $new_str .= $str2;
    return $new_str;
}
